package com.fastloan.mgt.invest.controller.comm;

import com.fastloan.common.excel.ExcelUt;
import com.fastloan.common.excel.Form;
import com.fastloan.common.excel.Sheet;
import com.fastloan.mgt.application.base.util.CodeUtil;
import com.fastloan.mgt.invest.model.InvestType;
import com.fastloan.mgt.invest.model.count.*;
import com.fastloan.mgt.invest.service.InvestFromService;
import com.fastloan.mgt.invest.service.InvestTypeService;
import com.fastloan.safe.core.util.ManagerKit;
import com.kawins.result.ResultTo;
import org.apache.poi.hssf.util.HSSFColor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Created by gelon on 2017/10/16.
 * 问卷统计
 */
@RestController
@RequestMapping("/api/invest/count")
public class InvestCountController {

    @Autowired
    InvestFromService investFromService;

    @Autowired
    InvestTypeService investTypeService;

    /**
     * 统计单个调查问卷的信息
     */
    @GetMapping("/{subjectId}")
    public ResultTo countQuestions(@PathVariable("subjectId") String subjectId) {
        Questionnaire questionnaire = questionsFromAnswerDetails(subjectId, ManagerKit.getTopOrgId().toString());
        return new ResultTo().setData(questionnaire);
    }

    private Questionnaire questionsFromAnswerDetails(@PathVariable("subjectId") String subjectId, String topOrgId) {
        List<AnswerDetail> answerDetails = investFromService.questdetaions(subjectId, topOrgId);
        Map<String, List<BaseQuestion>> map = new HashMap<>();
        for (AnswerDetail answerDetail : answerDetails) {
            mapPush(answerDetail, map);
        }
        changeTypeName(map);
        generatorCountInfo(map);
        return new Questionnaire(answerDetails.get(0).getTitle(), map);
    }

    private void generatorCountInfo(Map<String, List<BaseQuestion>> map) {
        map.forEach((key, value) -> value.forEach(this::generatorChoice));
    }

    private void generatorChoice(BaseQuestion baseQuestion) {
        if (baseQuestion instanceof ChoiceQuestion) {
            ChoiceQuestion choiceQuestion = (ChoiceQuestion) baseQuestion;
            choiceQuestion.generatorAnsPercentage();
        }
    }

    private void changeTypeName(Map<String, List<BaseQuestion>> map) {
        List<String> removeList = new ArrayList<>();
        Map<String,List<BaseQuestion>> add = new HashMap<>();
        for (Map.Entry<String, List<BaseQuestion>> entry : map.entrySet()) {
            if ("默认报告".equals(entry.getKey())) {
                continue;
            }
            try {
                InvestType investType = investTypeService.selectByPrimaryKey(entry.getKey());
                if (investType == null) {
                    continue;
                }
                add.put(investType.getName(), entry.getValue());
                removeList.add(entry.getKey());
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        for (String removeKey : removeList) {
            map.remove(removeKey);
        }
        map.putAll(add);
    }


    public void mapPush(AnswerDetail answerDetail, Map<String, List<BaseQuestion>> map) {
        if (answerDetail.getTypeIds() == null || "".equals(answerDetail.getTypeIds()) || "0".equals(answerDetail.getTypeIds())) {
            mapPush("默认报告", answerDetail, map);
        } else {
            String[] modules = answerDetail.getTypeIds().split(",");
            for (String module : modules) {
                if (module != null && !module.trim().equals("")) {
                    mapPush(module.trim(), answerDetail, map);
                }
            }
        }
    }

    public void mapPush(String module, AnswerDetail answerDetail, Map<String, List<BaseQuestion>> map) {
        if (!map.containsKey(module)) {
            map.put(module, new ArrayList<>());
        }
        pushQuestion(map.get(module), answerDetail);
    }

    private void pushQuestion(List<BaseQuestion> baseQuestions, AnswerDetail answerDetail) {
        for (BaseQuestion baseQuestion : baseQuestions) {
            if (baseQuestion.getDetail().equals(answerDetail.getCname())) {
                if (baseQuestion instanceof ChoiceQuestion) {
                    parseCurrQuest((ChoiceQuestion) baseQuestion, answerDetail);
                } else {
                    parseCurrQuest((TextQuestion) baseQuestion, answerDetail);
                }
                return;
            }
        }
        if (answerDetail.getType() == 1 || answerDetail.getType() == 2) {
            ChoiceQuestion choiceQuestion = new ChoiceQuestion(buildAnscounts(answerDetail), answerDetail.getCname(),
                typeName(answerDetail.getType()));
            baseQuestions.add(choiceQuestion);
            parseCurrQuest(choiceQuestion, answerDetail);
        } else if (answerDetail.getType() == 3) {
            TextQuestion textQuestion = new TextQuestion(new ArrayList<>(), answerDetail.getCname(), typeName(answerDetail.getType()));
            baseQuestions.add(textQuestion);
            parseCurrQuest(textQuestion, answerDetail);
        }
    }

    private List<AnswerCount> buildAnscounts(AnswerDetail answerDetail) {
        String[] answers = answerDetail.getAnswerOptions().split(",");
        List<AnswerCount> answerCounts = new ArrayList<>();
        for (String ans : answers) {
            if (ans != null && !"".equals(ans)) {
                answerCounts.add(new AnswerCount()
                    .setDetails(ans)
                    .setNum(0)
                    .setAnswerDetails(new ArrayList<>()));
            }
        }
        if (answerDetail.getHaveOther() == 1) {
            answerCounts.add(new AnswerCount()
                .setDetails("其他")
                .setNum(0)
                .setAnswerDetails(new ArrayList<>()));
        }
        return answerCounts;
    }

    String typeName(int i) {
        if (i == 1) {
            return "单选";
        } else if (i == 2) {
            return "多选";
        } else {
            return "填空";
        }
    }


    void parseCurrQuest(ChoiceQuestion choiceQuestion, AnswerDetail answerDetail) {
        addChoiceNum(answerDetail, choiceQuestion);
    }


    private void addChoiceNum(AnswerDetail answerDetail, ChoiceQuestion choiceQuestion) {
        AnswerCount otherAns = null;
        choiceQuestion.pushAns(answerDetail.getCusTempId());
        for (AnswerCount answerCount : choiceQuestion.getAnswerCounts()) {
            if ("其他".equals(answerCount.getDetails())) {
                otherAns = answerCount;
                continue;
            }
            if (answerCount.getDetails().equals(answerDetail.getValue())) {
                answerCount.plusNum();
                return;
            }
        }
        if (otherAns != null) {
            otherAns.plusNum();
            otherAns.getAnswerDetails().add(answerDetail);
        }
    }

    void parseCurrQuest(TextQuestion textQuestion, AnswerDetail answerDetaion) {
        textQuestion.pushAns(answerDetaion.getCusTempId());
        textQuestion.getAnswerDetails().add(answerDetaion);
    }


    int START_ANS = 2;

    @GetMapping("/outExcel")
    public void getExcel(String subjectId, String moduleName, HttpServletResponse response) {
        Questionnaire questionnaire = questionsFromAnswerDetails(subjectId, ManagerKit.getTopOrgId().toString());
        List<BaseQuestion> baseQuestions = questionnaire.getContent().get(moduleName);
        List<Sheet> sheets = new ArrayList<>();
        IntStream.range(0, baseQuestions.size()).forEach(idx -> sheets.add(createSheet(baseQuestions.get(idx), idx)));
        ExcelUt.resPonse(response, moduleName, sheets);
    }

    private Sheet createSheet(BaseQuestion baseQuestion, int idx) {
        Sheet sheet = new Sheet("Q" + (idx + 1));
        new Form(0, 0, 0, 7, HSSFColor.ROYAL_BLUE.index, HSSFColor.WHITE.index, (short) 12,
            baseQuestion.getDetail() + "(" + baseQuestion.getTypeName() + ")")
            .setBold(true).to(sheet);
        if (baseQuestion instanceof ChoiceQuestion) {
            ChoiceQuestion choiceQuestion = (ChoiceQuestion) baseQuestion;
            new Form(START_ANS, 0, HSSFColor.BLACK.index, "答案选项").setBackgroundColor(HSSFColor.AQUA.index).to(sheet);
            new Form(START_ANS, 1, HSSFColor.BLACK.index, "回复情况").setBackgroundColor(HSSFColor.AQUA.index).to(sheet);
            IntStream.range(0, choiceQuestion.getAnswerCounts().size())
                .forEach(index -> createChoiceAns(index, choiceQuestion.getAnswerCounts().get(index), 3, sheet));
            new Form(START_ANS + 1 + choiceQuestion.getAnswerCounts().size(), 0, "受访人数").setBackgroundColor(HSSFColor.LIGHT_GREEN.index).to(sheet);
            new Form(START_ANS + 1 + choiceQuestion.getAnswerCounts().size(), 1, choiceQuestion.getNum() + "")
                .setBackgroundColor(HSSFColor.LIGHT_GREEN.index).to(sheet);
            List<AnswerCount> moreInfo = choiceQuestion.getAnswerCounts().stream()
                .filter(answerCount -> !CodeUtil.noneValueList(answerCount.getAnswerDetails())).collect(Collectors.toList());
            IntStream.range(0, moreInfo.size()).forEach(index -> createMoreTable(moreInfo.get(index), 3, index, 3, sheet));
        } else if (baseQuestion instanceof TextQuestion) {
            TextQuestion textQuestion = (TextQuestion) baseQuestion;
            createMoreTable("答案", textQuestion.getAnswerDetails(), sheet, 0, HSSFColor.BLACK.index);
            new Form(START_ANS + 1 + textQuestion.getAnswerDetails().size(), 0, "受访人数" + textQuestion.getNum())
                .setBackgroundColor(HSSFColor.LIGHT_GREEN.index).to(sheet);
        }
        return sheet;
    }


    private void createMoreTable(AnswerCount answerCount, int startPos, int index, int jumpColumn, Sheet sheet) {
        int currColumn = startPos + index * jumpColumn;
        short borderColor = HSSFColor.BLACK.index;
        createMoreTable("在--" + answerCount.getDetails() + "  中填写的内容", answerCount.getAnswerDetails(), sheet, currColumn, borderColor);
    }

    private void createMoreTable(String title, List<AnswerDetail> answerDetails, Sheet sheet, int currColumn, short borderColor) {
        new Form(START_ANS, currColumn, borderColor, title).setBackgroundColor(HSSFColor.AQUA.index).to(sheet);
        IntStream.range(0, answerDetails.size())
            .forEach(idx -> new Form(idx + START_ANS + 1, currColumn, borderColor, answerDetails.get(idx).getValue()).to(sheet));
    }

    private void createChoiceAns(int idx, AnswerCount answerCount, int startIndex, Sheet sheet) {
        new Form(idx + startIndex, 0, HSSFColor.BLACK.index, answerCount.getDetails()).to(sheet);
        new Form(idx + startIndex, 1, HSSFColor.BLACK.index, answerCount.getNum() + "").to(sheet);
    }


}
